package com.weimob.mcloud.wechatwork.customer.service.impl;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.fastjson.JSON;
import com.weimob.mcloud.mcloudratelimitercore.common.RatelimiterInfo;
import com.weimob.mcloud.mcloudratelimitercore.common.enums.LimitKeyEnum;
import com.weimob.mcloud.mcloudratelimitercore.common.utils.LimitKeyUtils;
import com.weimob.mcloud.wechatwork.common.enums.CommonBizErrorEnum;
import com.weimob.mcloud.wechatwork.core.adapter.enums.channel.WechatWorkAppType;
import com.weimob.mcloud.wechatwork.core.adapter.pojo.dto.channel.base.Request;
import com.weimob.mcloud.wechatwork.core.adapter.pojo.dto.channel.request.tag.*;
import com.weimob.mcloud.wechatwork.core.adapter.service.BcAdapterService;
import com.weimob.mcloud.wechatwork.core.adapter.service.ChannelTagAdapterService;
import com.weimob.mcloud.wechatwork.core.entity.privatesphere.PrivateSphere;
import com.weimob.mcloud.wechatwork.core.enums.privateSphere.PrivateSphereEncryptCorpEnum;
import com.weimob.mcloud.wechatwork.core.service.privatesphere.PrivateSphereService;
import com.weimob.mcloud.wechatwork.customer.convertor.tag.TagConvert;
import com.weimob.mcloud.wechatwork.customer.domain.dto.CorpExternalUserTag;
import com.weimob.mcloud.wechatwork.customer.service.ChannelTagService;
import com.weimob.mcloud.wechatwork.customer.service.user.module.dto.tag.v2.CorpTagGroupDTO;
import com.weimob.mcloud.wechatwork.customer.service.user.module.dto.tag.v2.DelCorpTagDTO;
import com.weimob.mcloud.wechatwork.customer.service.user.module.dto.tag.v2.EditCorpTagOrGroup;
import com.weimob.mcloud.wechatwork.customer.service.user.module.dto.tag.v2.MarkTagCallbackDTO;
import com.weimob.soa.common.response.SoaResponse;
import com.weimob.soa.common.utils.SoaUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;

import static com.weimob.mcloud.wechatwork.customer.service.user.enums.TagBizErrorEnum.AUTHORIZE_AUTH;
import static com.weimob.mcloud.wechatwork.customer.service.user.enums.TagBizErrorEnum.NOT_FIND_PRIVATE_SPHERE;

/**
 * @author junlong.lv
 * @version 1.0
 * @date 2022/3/14 2:14 下午
 */
@Service
@Slf4j
public class ChannelTagServiceImpl implements ChannelTagService {

    @Reference(filter = "ratelimiter")
    private ChannelTagAdapterService channelTagAdapterService;

    @Resource
    private BcAdapterService bcAdapterService;

    @Autowired
    private RedisTemplate<String, RatelimiterInfo> redisTemplate;

    @Reference
    private PrivateSphereService privateSphereService;

    @Value("${aewc.productId:203}")
    private Long aewcProductId;

    @Override
    public SoaResponse<CorpTagGroupAdapterDTO, Void> addCorpTag(CorpTagGroupDTO corpTagGroupDTO, PrivateSphere responseVo) {

        CorpTagGroupAdapterDTO corpTagGroupAdapterDTO = TagConvert.toCorpTagGroupAdapterDTO(corpTagGroupDTO);

        Request<CorpTagGroupAdapterDTO> request = new Request<>();

        if (PrivateSphereEncryptCorpEnum.CIPHER.getCode().equals(responseVo.getEncryptCorpId())) {
            request.setTemplateId(responseVo.getTemplateId());
            request.setType(WechatWorkAppType.PROXIED_INTERNAL_APP.getType());

        } else {
            request.setType(WechatWorkAppType.CONTACT.getType());
        }

        request.setProviderIdentity(responseVo.getChannelProviderIdentity());

        request.setCorpId(corpTagGroupDTO.getCorpId());
        request.setData(corpTagGroupAdapterDTO);
        return channelTagAdapterService.addCorpTag(request);
    }

    @Override
    public SoaResponse<Boolean, ?> editCorpTag(EditCorpTagOrGroup editCorpTagOrGroup, PrivateSphere responseVo) {

        Request<EditCorpTag> request = new Request<>();
        request.setCorpId(editCorpTagOrGroup.getCorpId());

        if (PrivateSphereEncryptCorpEnum.CIPHER.getCode().equals(responseVo.getEncryptCorpId())) {
            request.setTemplateId(responseVo.getTemplateId());
            request.setType(WechatWorkAppType.PROXIED_INTERNAL_APP.getType());

        } else {
            request.setType(WechatWorkAppType.CONTACT.getType());
        }

        request.setProviderIdentity(responseVo.getChannelProviderIdentity());

        EditCorpTag editCorpTag = new EditCorpTag();
        editCorpTag.setId(editCorpTagOrGroup.getId());
        editCorpTag.setName(editCorpTagOrGroup.getName());
        editCorpTag.setTagType(editCorpTagOrGroup.getTagType());

        request.setData(editCorpTag);

        return channelTagAdapterService.editCorpTag(request);
    }

    @Override
    public SoaResponse<Boolean, ?> delCorpTag(DelCorpTagDTO delCorpTagDTO, PrivateSphere responseVo) {
        if (null == responseVo) {
            return SoaUtil.error(NOT_FIND_PRIVATE_SPHERE.getCode(), NOT_FIND_PRIVATE_SPHERE.getDesc(), false);
        }

        Request<DelCorpTag> request = new Request<>();
        request.setCorpId(delCorpTagDTO.getCorpId());
        if (PrivateSphereEncryptCorpEnum.CIPHER.getCode().equals(responseVo.getEncryptCorpId())) {
            request.setTemplateId(responseVo.getTemplateId());
            request.setType(WechatWorkAppType.PROXIED_INTERNAL_APP.getType());

        } else {
            request.setType(WechatWorkAppType.CONTACT.getType());
        }

        request.setProviderIdentity(responseVo.getChannelProviderIdentity());
        DelCorpTag delCorpTag = new DelCorpTag();
        delCorpTag.setGroupIdList(delCorpTagDTO.getGroupIdList());
        delCorpTag.setTagIdList(delCorpTagDTO.getTagIdList());
        request.setData(delCorpTag);

        return channelTagAdapterService.delCorpTag(request);
    }

    @Override
    public Boolean addUserTag(CorpExternalUserTag corpExternalUserTag, PrivateSphere responseVo) {
        if (null == responseVo) {
            return false;
        }

        Request<MarkCorpTag> request = new Request<>();
        request.setCorpId(corpExternalUserTag.getCorpId());
        if (PrivateSphereEncryptCorpEnum.CIPHER.getCode().equals(responseVo.getEncryptCorpId())) {
            request.setTemplateId(responseVo.getTemplateId());
            request.setType(WechatWorkAppType.PROXIED_INTERNAL_APP.getType());

        } else {
            request.setType(WechatWorkAppType.CONTACT.getType());
        }

        request.setProviderIdentity(responseVo.getChannelProviderIdentity());
        MarkCorpTag markCorpTag = new MarkCorpTag();
        markCorpTag.setAddTag(corpExternalUserTag.getAddTag());
        markCorpTag.setRemoveTag(corpExternalUserTag.getRemoveTag());
        markCorpTag.setExternalUserId(corpExternalUserTag.getExternalUserId());
        markCorpTag.setUserId(corpExternalUserTag.getUserId());

        request.setData(markCorpTag);

        SoaResponse<Boolean, Void> booleanVoidSoaResponse = channelTagAdapterService.markTag(request);
        return SoaUtil.unpack(booleanVoidSoaResponse);
    }

    @Override
    public SoaResponse<MarkCropTagDTO, Void> addUserTagV2(CorpExternalUserTag corpExternalUserTag, Long taskId, String type) {
        //查询私域信息
        PrivateSphere privateSphereRequest = new PrivateSphere();
        privateSphereRequest.setCorpId(corpExternalUserTag.getCorpId());
        privateSphereRequest.setBosId(corpExternalUserTag.getBosId());
        privateSphereRequest.setProductId(aewcProductId);
        SoaResponse<PrivateSphere, Void> fetchSoa = privateSphereService.fetch(privateSphereRequest);
        if (0L != Long.parseLong(fetchSoa.getReturnCode())) {
            return SoaUtil.error(AUTHORIZE_AUTH.getCode(), AUTHORIZE_AUTH.getDesc(), null);
        }

        PrivateSphere responseVo = fetchSoa.getResponseVo();
        Request<MarkCorpTag> request = new Request<>();
        request.setCorpId(corpExternalUserTag.getCorpId());
        if (PrivateSphereEncryptCorpEnum.CIPHER.getCode().equals(responseVo.getEncryptCorpId())) {
            request.setTemplateId(responseVo.getTemplateId());
            request.setType(WechatWorkAppType.PROXIED_INTERNAL_APP.getType());
        } else {
            request.setType(WechatWorkAppType.CONTACT.getType());
        }
        request.setProviderIdentity(responseVo.getChannelProviderIdentity());
        /**
         * 回调的taskId 一定要被传递
         * RateLimiterBizParam 离线和实时，
         */
        request.setTaskId(taskId);
        request.setRateLimiterBizParam(type);

        MarkCorpTag markCorpTag = new MarkCorpTag();
        markCorpTag.setAddTag(corpExternalUserTag.getAddTag());
        markCorpTag.setRemoveTag(corpExternalUserTag.getRemoveTag());
        markCorpTag.setExternalUserId(corpExternalUserTag.getExternalUserId());
        markCorpTag.setUserId(corpExternalUserTag.getUserId());

        request.setData(markCorpTag);
        SoaResponse<MarkCropTagDTO, Void> response = channelTagAdapterService.markTagV2(request);
        if (CommonBizErrorEnum.WECHAT_WORK_LIMIT.getCode().equals(response.getReturnCode())) {
            taskId = response.getResponseVo().getTaskId();
            log.info("打标签触发限流 code={},taskId={}", CommonBizErrorEnum.WECHAT_WORK_LIMIT.getCode(), taskId);
            //触发限流
            MarkTagCallbackDTO markTagCallbackDTO = new MarkTagCallbackDTO();
            markTagCallbackDTO.setCorpId(corpExternalUserTag.getCorpId());
            markTagCallbackDTO.setExternalUserId(corpExternalUserTag.getExternalUserId());
            markTagCallbackDTO.setUserId(corpExternalUserTag.getUserId());
            markTagCallbackDTO.setAddTag(corpExternalUserTag.getAddTag());
            markTagCallbackDTO.setRemoveTag(corpExternalUserTag.getRemoveTag());
            markTagCallbackDTO.setType(type);
            markTagCallbackDTO.setTaskId(taskId);
            RatelimiterInfo tag_mark = new RatelimiterInfo(LimitKeyEnum.TAG_MARK.getKey(), JSON.toJSONString(markTagCallbackDTO));
            redisTemplate.opsForValue().set(LimitKeyUtils.buildRedisKey(taskId), tag_mark, 1, TimeUnit.DAYS);
        }
        return response;
    }
}
